package com.lvan.websocket.chat.config;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;

/**
 * @author Lvan
 * ServerEndpoint("/websocket/{userId}"): 暴露对外访问的访问地址
 */
@ServerEndpoint("/websocket/{userId}")
@Component
public class WebSocketEndpoint {

    private static Logger log = LoggerFactory.getLogger(WebSocketEndpoint.class);

    /**
     * 与客户端的连接会话，需要通过它来给客户端发送数据
     */
    private Session session;

    /**
     * 连接建立成功调用的方法
     *
     * @param session 会话session
     * @param userId  用户ID
     */
    @OnOpen
    public void onOpen(Session session, @PathParam("userId") String userId) {
        // 将会话存入连接池
        if (StringUtils.hasText(userId)) {
            SessionPool.sessions.put(userId, session);
        }
    }

    /**
     * 断开连接
     *
     * @param session 会话Session
     */
    @OnClose
    public void onClose(Session session) {
        try {
            SessionPool.close(session.getId());
            session.close();
        } catch (IOException e) {
            log.error("[WebSocket]: session关闭失败，" + e.getMessage());
        }
    }

    /**
     * 收到客户端消息后调用的方法
     *
     * @param message msg
     * @param session session
     */
    @OnMessage
    public void onMessage(String message, Session session) {
        sendMessage(message);
    }

    /**
     * 点对点发送消息
     *
     * @param user    目标用户
     * @param message msg
     */
    public void sendMessage(String user, String message) {
        if (SessionPool.sessions.containsKey(user)) {
            SessionPool.sessions.get(user).getAsyncRemote().sendText(message);
        }
    }

    /**
     * 群发消息
     *
     * @param message msg
     */
    public void sendMessage(String message) {
        for (String sessionId : SessionPool.sessions.keySet()) {
            SessionPool.sessions.get(sessionId).getAsyncRemote().sendText(message);
        }
    }

}
